#ifndef FDATASOURCE_H
#define FDATASOURCE_H

#ifdef _WIN32
#include <windows.h>
#define OWENIO_NOT_USE_IMPORTLIB 1
#include "owen_io.h"

#include <QVariant>
#include <QHash>
#include <QStringList>

extern TProcReadUInt ReadUInt;
extern TProcReadFloat24 ReadFloat;
extern TProcReadIEEE32 ReadIEEE;
#endif

#include <QString>

#include <QMap>
#include <QList>
#include <QLibrary>


enum ValueStatus
{
    VS_Normal=0,
    VS_Bad
};

class CValue
{
protected:
    double value;
    ValueStatus status;
public:
    CValue(double val):value(val),status(VS_Normal){}
    CValue():status(VS_Bad){} //Generate fail
    CValue(const CValue &v):value(v.value),status(v.status){}

    double getValue(){
         if (status == VS_Normal) return value;
         else return 0;
    };
    ValueStatus getStatus(){return status;}
};

class CEditableValue : public CValue
{
public:
    CEditableValue(): CValue(){}
    CEditableValue(double val): CValue(val){}
    void setValue(double val) {value = val; status = VS_Normal;}
    void setFail(){value =0; status = VS_Bad;}
};


class FDataSource
{
protected:
    QVariant parameter;
public:
    FDataSource(QVariant parameter):parameter(parameter){}
    virtual ~FDataSource(){}
    virtual CValue readValue()=0;
};

class FDataSourceConstructor
{
    QString name;
public:
    FDataSourceConstructor(QString name):name(name){}
    virtual FDataSource* create(QVariant params)=0;
    QString getName(){return name;}
};



class FDataSourceFactory
{
private:
    QHash<QString,FDataSourceConstructor*> creators;
    QHash<QString,QLibrary* > loadedLibraries;
public:
    FDataSourceFactory();
    ~FDataSourceFactory();
    void addConstructor(FDataSourceConstructor* c){creators[c->getName()]=c;}
    FDataSource* create(QString type, QVariant params){
        if (creators.contains(type)) return creators[type]->create(params);
        else return NULL;
    }

};

extern FDataSourceFactory* dataSourceFactory;

#endif
